package com.hx.tx.springboot.aop;

import com.hx.tx.springboot.util.TransactionUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;

/**
 * @author jxlgcmh
 * @date 2020-05-18 00:12
 * @description
 */
//@Aspect
//@Component
//@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)  //防止单例线程安全问题
public class TransactionalAop {

    @Autowired
    private TransactionUtils transactionUtils;

    /**
     * 注意切面怎么写
     */
    @Pointcut("execution(public * com.hx.tx.springboot.service..*.*(..))")
    public void pointCut() {
    }

    /*** @Before 在目标方法之前切入；切入点表达式（指定在哪个方法切入） */
    @Before("pointCut()")
    public void logStart(JoinPoint joinPoint) {
        System.out.println(">>前置通知");
    }

    @After("pointCut()")
    public void logEnd(JoinPoint joinPoint) {
        System.out.println(">>后置通知");
    }

    /***JoinPoint一定要出现在参数表的第一位*/
    @AfterReturning(value = "pointCut()", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println(">>方法执行结束后运行");
    }

    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void logException(JoinPoint joinPoint, Exception exception) {
        System.out.println(">>异常通知");
    }

    @Around("pointCut()")
    public Object logAround(ProceedingJoinPoint pjd) throws Throwable {
        TransactionStatus begin = transactionUtils.begin();
        try {
            Object proceed = pjd.proceed();
            transactionUtils.commit(begin);
            return proceed;
        } catch (Exception e) {
            transactionUtils.rollback(begin);
            return "事务已回滚!";
        }
    }
}

